package com.biostime.qdingding.modules.qd.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;

/**
 * 日历操作
 * @author phil
 * @version 2015-11-10
 */
public class CalendarUtils {
	
	public static Map<Integer,String> Weeks;
	
	static{
		Weeks = new HashMap<Integer,String>();
		Weeks.put(1, "星期日");
		Weeks.put(2, "星期一");
		Weeks.put(3, "星期二");
		Weeks.put(4, "星期三");
		Weeks.put(5, "星期四");
		Weeks.put(6, "星期五");
		Weeks.put(7, "星期六");
	}
	
	public static List<Date> calcOnDate(Date ondate, Date fstart, Date tend) {
		
		Calendar calendar = Calendar.getInstance();    
		calendar.setTime(ondate);
		
		int weekday = calendar.get(Calendar.DAY_OF_WEEK);
		
		calendar.setTime(fstart);
		int fweekday = calendar.get(Calendar.DAY_OF_WEEK);
		
		calendar.add(Calendar.DATE, weekday-fweekday);
		
		Date start = calendar.getTime();
		
		List<Date> ondates = Lists.newArrayList();
		
		while(start.compareTo(tend)<=0){
			start = calendar.getTime();
			if(start.compareTo(fstart)>=0 && start.compareTo(tend)<=0){
				ondates.add(start);
			}
			
			calendar.add(Calendar.DATE, 7);
		}
		
		return ondates;
	}
	
	/**  
     * 计算两个日期之间相差的天数  
     * @param smdate 较小的时间 
     * @param bdate  较大的时间 
     * @return 相差天数 
     * @throws ParseException  
     */    
    public static int daysBetween(Date smdate,Date bdate)
    {    try{
	    	//SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
	        //smdate=sdf.parse(sdf.format(smdate));  
	        //bdate=sdf.parse(sdf.format(bdate));  
	        Calendar cal = Calendar.getInstance();    
	        cal.setTime(smdate);    
	        long time1 = cal.getTimeInMillis();                 
	        cal.setTime(bdate);    
	        long time2 = cal.getTimeInMillis();         
	        long between_days=(time2-time1)/(1000*3600*24);  
	            
	       return Integer.parseInt(String.valueOf(between_days));         
	    }catch(Exception ex){
	    	
	    }
        return -1;  
    }    
	
	/***
	 * 获取任意年的周数
	 * @param weekYear
	 * @return 任意年周数组
	 */
	public static List<WeekInfo> getWeeksInYear(int weekYear){
		try{
			DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			Date yearStart = sdf.parse(String.format("%s-01-01 00:00:00", weekYear));
			Date yearEnd = sdf.parse(String.format("%s-12-31 23:59:59", weekYear));
			
			Date weekStart = yearStart;//一周开始日期
			Date weekEnd = yearStart;//一周结束日期
			
			Calendar calendar = Calendar.getInstance();
			calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置星期一为一周的开始
			calendar.setTime(yearStart);
			
			//int weekStart = calendar.get(Calendar.WEEK_OF_YEAR);//获取当前日期是一年中第几周
			int weekDay = calendar.get(Calendar.DAY_OF_WEEK);//获取星期几
			
			weekDay = weekDay==1 ? 7 : (weekDay-1);//转化星期一为一周的开始
			
			//获取一年第一周的第一天
			calendar.add(Calendar.DATE, 1-weekDay);
			weekStart = calendar.getTime();
			
			List<WeekInfo> weeks = Lists.newArrayList();
			
			int weekCount = 1;
			while(weekStart.compareTo(yearEnd)<=0){
				
				//获取一周最后一天
				calendar.add(Calendar.DATE, 6);
				weekEnd = calendar.getTime();
				
				WeekInfo week = new WeekInfo();
				week.setWeekOfYear(weekCount);
				week.setStart(weekStart);
				week.setEnd(weekEnd);
				weeks.add(week);
				
				//获取一周第一天
				calendar.add(Calendar.DATE, 1);
				weekStart = calendar.getTime();
				
				weekCount++;
			}
			
			return weeks;
		}catch(Exception ex){
			return null;
		}
	}
	
	/***
	 * 获取任意年的周数
	 * @param weekYear
	 * @param weekOfYear
	 * @return 任意年的周数
	 */
	public static int getWeeksInYear(int weekYear, int weekOfYear){
		Calendar calendar = Calendar.getInstance();  
		calendar.setWeekDate(weekYear, weekOfYear, 1);
		
		return calendar.getWeeksInWeekYear();
	}
	
	/**
	 * 获取当前月天
	 * @param date
	 * @return
	 */
	public static MonthInfo getMonth(int year, int month){
		Calendar calendar = Calendar.getInstance();  
		
		calendar.clear();
		calendar.set(year, month-1, 1);
		
		MonthInfo monthInfo = new CalendarUtils.MonthInfo();
		
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
		monthInfo.setDayOfWeek(dayOfWeek);
		
		int dayCount = getMonthDays(year,month);
		
		for(int i=1;i<=dayCount;i++){
			MonthCell cell = new MonthCell();
			cell.setDay(i);
			monthInfo.addCell(cell);
		}
		
		return monthInfo;
	}
	
	/**
	 * 判断一个月有多少天  
	 * @param month
	 * @return
	 */
	private static int getMonthDays(int year, int month) {
		int days = 0;
		
        if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12){  
            days = 31;  
        }  
        if(month==4 || month==6 || month==9 || month==11){  
            days = 30;  
        }  
        if(month == 2){  
            if(((year%4==0)&&(year%100!=0))||(year%400==0)){  
                days = 29;  
            }else{  
                days = 28;  
            }  
        }  
		
		return days;
	}
	
	/**
	 * 获取指定日期的星期信息
	 * @param weekOfYear 第几周
	 * @return
	 */
	public static WeekInfo getWeek(int weekYear, int weekOfYear){
		Calendar calendar = Calendar.getInstance();  
		calendar.setWeekDate(weekYear, weekOfYear, 1);
		
		WeekInfo week = new CalendarUtils.WeekInfo();
		week.setWeekOfYear(calendar.get(Calendar.WEEK_OF_YEAR));
		
		for(int i=1;i<=7;i++){
			calendar.add(Calendar.DATE, (i-calendar.get(Calendar.DAY_OF_WEEK)));
			
			WeekCell cell = new WeekCell();
			cell.setDate(calendar.getTime());
			cell.setName(Weeks.get(i));
			
			week.addCell(cell);
		}
		
		return week;
	}
	
	/**
	 * 获取指定日期的星期信息
	 * @param weekOfYear 第几周
	 * @return
	 */
	public static WeekInfo getWeek2(int weekYear, int weekOfYear){
		Calendar calendar = Calendar.getInstance();  
		calendar.setWeekDate(weekYear, weekOfYear, 1);
		
		WeekInfo week = new CalendarUtils.WeekInfo();
		week.setWeekOfYear(calendar.get(Calendar.WEEK_OF_YEAR));
		
		for(int i=2;i<=8;i++){
			calendar.add(Calendar.DATE, (i-calendar.get(Calendar.DAY_OF_WEEK)));
			
			WeekCell cell = new WeekCell();
			cell.setDate(calendar.getTime());
			cell.setName(Weeks.get(i==7 ? 7 : i%7));
			
			week.addCell(cell);
		}
		
		return week;
	}
	
	public static class MonthInfo{
		
		private int dayOfWeek;
		private List<MonthCell> cells = new ArrayList<MonthCell>();
		
		public void addCell(MonthCell cell){
			if(cells==null) cells = new ArrayList<MonthCell>();
			cells.add(cell);
		}
		
		public List<MonthCell> getCells() {
			return cells;
		}

		public void setCells(List<MonthCell> cells) {
			this.cells = cells;
		}

		public int getDayOfWeek() {
			return dayOfWeek;
		}

		public void setDayOfWeek(int dayOfWeek) {
			this.dayOfWeek = dayOfWeek;
		}
		
		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			
			int i=1;
			for(;i<dayOfWeek;i++){
				sb.append("  " + " ");
			}
			
			for(MonthCell cell : cells){
				sb.append(String.format("%2d", cell.getDay()) + " ");
				
				if(i%7==0){
					sb.append("\n");
				}
				i++;
			}
			
			return sb.toString();
		}
	}
	
	public static class MonthCell{
		private int day;

		public int getDay() {
			return day;
		}

		public void setDay(int day) {
			this.day = day;
		}
	}
	
	public static class WeekInfo{
		
		private int weekOfYear;
		private Date start;
		private Date end;
		
		private List<WeekCell> cells = new ArrayList<WeekCell>();
		
		public void addCell(WeekCell cell){
			if(cells==null) cells = new ArrayList<WeekCell>();
			cells.add(cell);
		}
		
		public int getWeekOfYear() {
			return weekOfYear;
		}

		public void setWeekOfYear(int weekOfYear) {
			this.weekOfYear = weekOfYear;
		}

		public List<WeekCell> getCells() {
			return cells;
		}

		public void setCells(List<WeekCell> cells) {
			this.cells = cells;
		}
		
		/**
		 * 显示一周信息
		 * @return
		 */
		public String text(){
			DateFormat sdf = new SimpleDateFormat("MM.dd");
			
			return String.format("第%s周[%s~%s]", weekOfYear, sdf.format(start),sdf.format(end));
		}
		
		/**
		 * 显示一周信息
		 * @return
		 */
		public String value(){
			DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			
			return String.format("%s~%s", sdf.format(start),sdf.format(end));
		}
		
		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			DateFormat sdf = new SimpleDateFormat("MM.dd");
			sb.append("{第"+weekOfYear+"周("+sdf.format(start)+"~"+sdf.format(end)+"):");
			for(WeekCell cell:cells){
				sb.append("["+cell.name+","+cell.date+"]");
			}
			sb.append("}");
			return sb.toString();
		}
		
		public void setStart(Date start){
			this.start = start;
		}
		
		public Date getStart() {
			if(this.cells!=null && this.cells.size()>0){
				start = this.cells.get(0).getDate();
			}
			
			return start;
		}
		
		public void setEnd(Date end){
			this.end = end;
		}
		
		public Date getEnd() {
			if(this.cells!=null && this.cells.size()>0){
				end = this.cells.get(this.cells.size()-1).getDate();
			}
			
			return end;
		}
	}
	
	public static class WeekCell{
		private Date date;
		private String name;

		public Date getDate() {
			return date;
		}

		public void setDate(Date date) {
			this.date = date;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
	}
}
